package net.love5z.web.common.session;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.love5z.web.common.cache.GaeCacheService;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class GaeCacheSessionFilter implements Filter {

    private FilterConfig config;

    private String       sessionCookieName    = "GAESESSIONID";

    private int          sessionExpireMinutes = 30;

    private String       sessionIdPrefix      = "gae.session";

    public GaeCacheSessionFilter() {
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;

        if (config.getInitParameter("sessionCookieName") != null) {
            this.sessionCookieName = config.getInitParameter("sessionCookieName");
        }

        if (config.getInitParameter("sessionIdPrefix") != null) {
            this.sessionIdPrefix = config.getInitParameter("sessionIdPrefix");
        }

        if (config.getInitParameter("sessionExpireMinutes") != null) {
            try {
                this.sessionExpireMinutes = Integer.parseInt(config
                    .getInitParameter("sessionExpireMinutes"));
            } catch (NumberFormatException e) {
                throw new ServletException("sessionExpireMinutes must be int in minutes");
            }
        }
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                                                                                             throws java.io.IOException,
                                                                                             ServletException {
        if ((request instanceof HttpServletRequest) && (response instanceof HttpServletResponse)) {
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            HttpServletResponse httpResponse = (HttpServletResponse) response;

            WebApplicationContext applicationContext = WebApplicationContextUtils
                .getWebApplicationContext(config.getServletContext());

            GaeCacheService gaeCacheService = (GaeCacheService) applicationContext
                .getBean("cacheService");

            //change the default getSession method to memcached getSession method
            GaeCacheSessionHttpRequest gaeCacheSessionHttpRequest = new GaeCacheSessionHttpRequest(
                gaeCacheService, httpRequest, httpResponse, sessionCookieName,
                sessionExpireMinutes, sessionIdPrefix);
            //just call destined servlet
            chain.doFilter(gaeCacheSessionHttpRequest, httpResponse);

            //save gae session after calling the servlet
            gaeCacheSessionHttpRequest.saveGaeSession();
        } else {
            //pass request back down the filter chain
            chain.doFilter(request, response);
        }

    }

    public void destroy() {
    }
}
